﻿

#include <pt.h>
#include "stdio.h"
#include "string.h"
#include "pt_mbus.h"
#include "pt_mbus_cli.h"

typedef struct
{
	pt_mbus_client_item_t cItem[PT_MBUS_CLIENT_COUNT_MAX];
}data_client_ctx_t;

//上下文信息
data_client_ctx_t g_s_data_client_ctx;

//获取一个空闲client索引
static uint8_t prvFindEmptyDatacHandle(void)
{
	data_client_ctx_t* ctx = &g_s_data_client_ctx;
	for (int i = 1; i < PT_MBUS_CLIENT_COUNT_MAX; i++)
	{
		if (ctx->cItem[i].vaild == PT_FALSE)
		{
			return i;
		}
	}

	return PT_MBUS_CLIENT_COUNT_MAX;
}

static uint8_t prvFindDatacHandleByCbkAndCtx(pt_mbus_callback_t cbk, void *user_data)
{
	data_client_ctx_t* ctx = &g_s_data_client_ctx;
	for (int i = 1; i < PT_MBUS_CLIENT_COUNT_MAX; i++)
	{
		pt_mbus_client_item_t* cItem = &ctx->cItem[i];
		if (cItem->vaild == PT_TRUE && cItem->cbk == cbk && cItem->user_data == user_data)
		{
			return i;
		}
	}

	return PT_MBUS_CLIENT_COUNT_MAX;
}

/**
 * @brief pt_mbus_subscribe
 * @param[in] topic_id  Topic id
 * @param[in] cbk  Callbacks to handel data service
 * @param[in] user_data param will passed to Callbacks
 * @retval   void
 */
void pt_mbus_subscribe(int topic_id, pt_mbus_callback_t cbk, void *user_data)
{
	data_client_ctx_t* ctx = &g_s_data_client_ctx;

	//查询一个空闲的client索引
	uint8_t handle = prvFindEmptyDatacHandle();

	if(handle >= PT_MBUS_CLIENT_COUNT_MAX) {
		PT_LOGE("[pt_mbus_subscribe]: no empty handle 0x%02x 0x%08x", topic_id, cbk);
		return;
	}

	pt_mbus_client_item_t* cItem = &ctx->cItem[handle];

	int index = pt_mbus_add_client(topic_id, cItem);

	if(index < 0) {
		PT_LOGE("[pt_mbus_subscribe]: client no empty slot 0x%02x 0x%08x", topic_id, cbk);
		return;
	}
	
	cItem->sItemIndex = pt_mbus_add_client(topic_id, cItem);
	cItem->vaild = PT_TRUE;
	cItem->cbk = cbk;
	cItem->user_data = user_data;
}

/**
 * @brief pt_mbus_unsubscribe
 * @param[in] cbk Callbacks to handel data service
 * @param[in] user_data param will passed to Callbacks
 * @retval void
 */
void pt_mbus_unsubscribe(int topic_id, pt_mbus_callback_t cbk, void *user_data)
{
	data_client_ctx_t* ctx = &g_s_data_client_ctx;

	uint8_t handle = prvFindDatacHandleByCbkAndCtx(cbk, user_data);

	if (handle == PT_MBUS_CLIENT_COUNT_MAX) return;

	pt_mbus_client_item_t* cItem = &ctx->cItem[handle];

	cItem->vaild = PT_FALSE;
	pt_mbus_remove_client(topic_id, cItem);
}
